﻿// ----------------------------------------------------------------------------------
// Microsoft Developer & Platform Evangelism
// 
// Copyright (c) Microsoft Corporation. All rights reserved.
// 
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
// EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// ----------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
// ----------------------------------------------------------------------------------

namespace Microsoft.Samples.BabelCam.Phone.ViewModel
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Text;
    using System.Windows;
    using System.Windows.Threading;
    using Microsoft.Phone.Tasks;
    using Microsoft.Samples.BabelCam.Phone.Models;
    using Microsoft.Samples.WindowsPhoneCloud.StorageClient;

    public class UploadPhotoPageViewModel : BaseViewModel
    {
        private readonly ICloudBlobClient blobClient;
        private readonly ICloudQueueClient queueClient;
        private readonly Dispatcher dispatcher;

        private List<LanguageChoice> availableLanguages;
        private string blobName;
        private Uri path;
        private bool isUploading;
        private string userNameIdentifier;
        private string toLanguage;
        private string fromLanguage;

        public UploadPhotoPageViewModel()
            : this(App.CloudClientFactory.ResolveCloudBlobClient("UploadAndList"), App.CloudClientFactory.ResolveCloudQueueClient("OcrRequests"), Deployment.Current.Dispatcher)
        {
        }

        public UploadPhotoPageViewModel(ICloudBlobClient blobClient, ICloudQueueClient queueClient, Dispatcher dispatcher)
        {
            this.queueClient = queueClient;
            this.blobClient = blobClient;
            this.dispatcher = dispatcher;

            this.availableLanguages = new List<LanguageChoice>()
            {
                new LanguageChoice { LanguageCode = "ar", LanguageName = "Arabic" },
                new LanguageChoice { LanguageCode = "bg", LanguageName = "Bulgarian" },
                new LanguageChoice { LanguageCode = "zh-CHS", LanguageName = "Chinese (Simplified)" },
                new LanguageChoice { LanguageCode = "zh-CHT", LanguageName = "Chinese (Traditional)" },
                new LanguageChoice { LanguageCode = "cs", LanguageName = "Czech" },
                new LanguageChoice { LanguageCode = "da", LanguageName = "Danish" }, 
                new LanguageChoice { LanguageCode = "nl", LanguageName = "Dutch" },
                new LanguageChoice { LanguageCode = "en", LanguageName = "English" },
                new LanguageChoice { LanguageCode = "et", LanguageName = "Estonian" },
                new LanguageChoice { LanguageCode = "fi", LanguageName = "Finnish" },
                new LanguageChoice { LanguageCode = "fr", LanguageName = "French" },
                new LanguageChoice { LanguageCode = "de", LanguageName = "German" },
                new LanguageChoice { LanguageCode = "el", LanguageName = "Greek" },
                new LanguageChoice { LanguageCode = "ht", LanguageName = "Haitian" },
                new LanguageChoice { LanguageCode = "he", LanguageName = "Hebrew" },
                new LanguageChoice { LanguageCode = "hu", LanguageName = "Hungarian" },
                new LanguageChoice { LanguageCode = "id", LanguageName = "Indonesian" },
                new LanguageChoice { LanguageCode = "it", LanguageName = "Italian" },
                new LanguageChoice { LanguageCode = "ja", LanguageName = "Japanese" },
                new LanguageChoice { LanguageCode = "ko", LanguageName = "Korean" },
                new LanguageChoice { LanguageCode = "lv", LanguageName = "Latvian" },
                new LanguageChoice { LanguageCode = "lt", LanguageName = "Lithuanian" },
                new LanguageChoice { LanguageCode = "no", LanguageName = "Norwegian" },
                new LanguageChoice { LanguageCode = "pl", LanguageName = "Polish" },
                new LanguageChoice { LanguageCode = "pt", LanguageName = "Portuguese" },
                new LanguageChoice { LanguageCode = "ro", LanguageName = "Romanian" },
                new LanguageChoice { LanguageCode = "ru", LanguageName = "Russian" },
                new LanguageChoice { LanguageCode = "sk", LanguageName = "Slovak" },
                new LanguageChoice { LanguageCode = "sl", LanguageName = "Slovenian" },
                new LanguageChoice { LanguageCode = "es", LanguageName = "Spanish" },
                new LanguageChoice { LanguageCode = "sv", LanguageName = "Swedish" },
                new LanguageChoice { LanguageCode = "th", LanguageName = "Thai" },
                new LanguageChoice { LanguageCode = "tr", LanguageName = "Turkish" },
                new LanguageChoice { LanguageCode = "uk", LanguageName = "Ukranian" },
                new LanguageChoice { LanguageCode = "vi", LanguageName = "Vietnamese" },
            };
        }

        public string BlobName
        {
            get
            {
                return this.blobName;
            }

            set
            {
                if (this.blobName != value)
                {
                    this.blobName = value;
                    this.NotifyPropertyChanged("BlobName");
                }
            }
        }

        public List<LanguageChoice> AvailableLanguages
        {
            get
            {
                return this.availableLanguages;
            }

            set
            {
                if (this.availableLanguages != value)
                {
                    this.availableLanguages = value;
                    this.NotifyPropertyChanged("AvailableLanguages");
                }
            }
        }

        public Uri Path
        {
            get
            {
                return this.path;
            }

            set
            {
                if (this.path != value)
                {
                    this.path = value;
                    this.NotifyPropertyChanged("Path");
                }
            }
        }

        public bool IsUploading
        {
            get
            {
                return this.isUploading;
            }

            set
            {
                if (this.isUploading != value)
                {
                    this.isUploading = value;
                    this.NotifyPropertyChanged("IsUploading");
                }
            }
        }

        public string UserNameIdentifier
        {
            get
            {
                return this.userNameIdentifier;
            }

            set
            {
                if (this.userNameIdentifier != value)
                {
                    this.userNameIdentifier = value;
                    this.NotifyPropertyChanged("UserNameIdentifier");
                }
            }
        }

        public string ToLanguage
        {
            get
            {
                return this.toLanguage;
            }

            set
            {
                if (this.toLanguage != value)
                {
                    this.toLanguage = value;
                    this.NotifyPropertyChanged("ToLanguage");
                }
            }
        }

        public string FromLanguage
        {
            get
            {
                return this.fromLanguage;
            }

            set
            {
                if (this.fromLanguage != value)
                {
                    this.fromLanguage = value;
                    this.NotifyPropertyChanged("FromLanguage");
                }
            }
        }

        public Stream PhotoStream { get; set; }

        public void LoadPhoto(Uri photoUri, Stream photoStream)
        {
            this.Path = photoUri;
            this.PhotoStream = photoStream;
        }

        public void UploadPhoto(Action<string> successCallback, Action<string> failureCallback)
        {
            this.IsUploading = true;
            this.blobClient.Upload(
                this.BlobName,
                this.PhotoStream,
                r => this.dispatcher.BeginInvoke(
                        () =>
                        {
                            this.IsUploading = false;

                            if (r.Exception == null)
                            {
                                AddRequestMessage(successCallback, failureCallback);
                            }
                            else
                            {
                                if (failureCallback != null)
                                {
                                    failureCallback.Invoke(string.Format(CultureInfo.InvariantCulture, "Error: {0}", r.Exception.Message));
                                }
                            }
                        }));
        }

        public void AddRequestMessage(Action<string> successCallback, Action<string> failureCallback)
        {
            string message = Helpers.Extensions.Serialize<OcrRequest>(
                                new OcrRequest { ContainerName = Application.Current.Resources["ImageContainerName"].ToString(), BlobName = this.blobName, FromLanguage = this.fromLanguage, ToLanguage = this.toLanguage, UserNameIdentifier = this.userNameIdentifier });

            this.queueClient.GetQueueReference(Application.Current.Resources["RequestQueueName"].ToString()).AddMessage(
                new CloudQueueMessage { AsBytes = Encoding.UTF8.GetBytes(message) },
                r => this.dispatcher.BeginInvoke(
                        () =>
                        {
                            this.IsUploading = false;

                            if (r.Exception == null)
                            {
                                successCallback.Invoke("Successfull upload");
                            }
                            else
                            {
                                if (failureCallback != null)
                                {
                                    failureCallback.Invoke(string.Format(CultureInfo.InvariantCulture, "Error: {0}", r.Exception.Message));
                                }
                            }
                        }));
        }
    }
}
